# -*- coding: utf-8 -*-
#
# Copyright (c) 2012, Rafael Pivato
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Rafael Pivato nor the names of its contributors
#       may be used to endorse or promote products derived from this
#       software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL RAFAEL PIVATO BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from google.appengine.ext import db
from google.appengine.api import memcache


class Guild(db.Model):
    """Represents guild information in a given time."""

    achievement_points = db.IntegerProperty(required=True, default='0',
                                            indexed=False)
    last_modified = db.IntegerProperty(required=True)
    level = db.IntegerProperty(required=True, indexed=False)
    name = db.StringProperty(required=True, indexed=False)
    realm = db.StringProperty(required=True, indexed=False)
    side = db.IntegerProperty(required=True, indexed=False)
    members_count = db.IntegerProperty(required=True, indexed=False)

    @classmethod
    def __fetch_members_since(cls):
        """Gets latest last_modified value from datastore."""
        query = Guild.all()
        query.order('-last_modified')
        entity = query.get()
        if entity:
            return entity.last_modified
        else:
            return 0

    @classmethod
    def members_since(cls):
        """This is a time stamp reference to know who is member of the guild.

        To determine who is member of the guild, we can get all Characters
        which member_until is greater or equal to this members_since.

        """
        value = memcache.get('members_since', cls.__module__)
        if value is None:
            value = cls.__fetch_members_since()
            memcache.set('members_since', value, namespace=cls.__module__)
        return value

    @classmethod
    def update(cls, guild, ranks={'admin': 0, 'officer': 0}):
        """Updates guild information using bcoma object."""

        # Verify the information we have is fresh
        if guild.last_modified > Guild.members_since():

            # Update members first, adjusting their member_until property
            for member in guild.members:
                Character.update_member(member, ranks)

            # Notify we can consider only members since this modification
            properties = {
                'achievement_points': guild.achievement_points,
                'last_modified': guild.last_modified,
                'level': guild.level,
                'name': guild.name,
                'realm': guild.realm,
                'side': guild.side,
                'members_count': len(guild.members),
            }
            model = Guild(**properties)
            model.put()
            memcache.set('members_since', guild.last_modified,
                         namespace=cls.__module__)


from wowgae.model.character import Character
